﻿using Newtonsoft.Json;
using StackExchange.Redis;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Tiens.NotificationHub.Abstractions.Store;
using Tiens.NotificationHub.Constant;
using Tiens.NotificationHub.Models;

namespace Tiens.NotificationHub.RedisStore
{
    public class AppConnectionStore : IAppConnectionStore
    {
        private readonly IDatabase _database;

        public AppConnectionStore(ConnectionMultiplexer redis)
        {
            _database = redis.GetDatabase();
        }

        public async Task<bool> RemoveConnectAsync(string groupName, string appId, string connectionId)
        {
            var redisKey = appId.ToAppConnectionRedisKey();

            var data = await _database.HashGetAsync(redisKey, groupName);
            if (data.IsNullOrEmpty)
                return true;

            var connections = JsonConvert.DeserializeObject<AppConnection>(data);

            connections.RemoveConnection(connectionId);

            return await _database.HashSetAsync(redisKey, groupName, JsonConvert.SerializeObject(connections));
        }

        public async Task<bool> AddConnectAsync(string userId, string appId, string connectionId)
        {
            var redisKey = appId.ToAppConnectionRedisKey();
            var groupName = userId.ToGroupName(appId);

            var data = await _database.HashGetAsync(redisKey, groupName);

            var connections = data.IsNullOrEmpty
                ? new AppConnection(userId, appId)
                : JsonConvert.DeserializeObject<AppConnection>(data);

            connections.AddConnection(connectionId);

            return await _database.HashSetAsync(redisKey, groupName, JsonConvert.SerializeObject(connections));
        }

        public async Task<IDictionary<string, AppConnection>> GetConnectionsAsync(string appId)
        {
            var redisKey = appId.ToAppConnectionRedisKey();

            var data = await _database.HashGetAllAsync(redisKey);

            return data.ToDictionary(x => x.Name.ToString(),
                x => x.Value.IsNullOrEmpty ? null : JsonConvert.DeserializeObject<AppConnection>(x.Value));
        }

    }
}
